package p2;
/**
 * This class implements a queue of customers as a circular buffer.
 */
public class CustomerQueue {
	private Customer[] customers; 
	private int first;
	private int last;
	private boolean test;
	private Gui gui;
	
	/**
	 * Creates a new customer queue.
	 * @param queueLength	The maximum length of the queue.
	 * @param gui			A reference to the GUI interface.
	 */
    public CustomerQueue(int queueLength, Gui gui) {
    	customers = new Customer[queueLength];
    	this.gui = gui;
    	first = 0;
    	last = 0;
	}
    
    public synchronized int getNextChair() throws InterruptedException
    {
    	if (isQueueFull()) wait();
    	notify();
    	return (last + 1) % customers.length;
    }
    
    public synchronized int getFirst() throws InterruptedException
    {
    	if (customers[first] == null) wait();
    	int pos = first;
    	notify();
    	return pos;
    }
    
    /**
     * Adds customers to the end of the queue. 
     * 
     * Works with global variables so it needs to be synchronized
     * 
     * @param customer
     * @throws InterruptedException 
     */
	public synchronized void addCustomer(Customer customer){
		while (isQueueFull()) {
			try { 
				wait();
			} catch(InterruptedException e) { }
		}
		
		customers[last] = customer;
		gui.fillLoungeChair(last, customer);
		incrementLast();
		
		notifyAll();
		
	}
	
	private boolean isQueueFull()
	{
		for(int i = 0; i < customers.length; ++i)
		{
			if(customers[i] == null)
				return false;
		}
		return true;
	}
	
	/**
	 * Returns the customer who is first in the queue
	 * 
	 * Works with global variables so it needs to be synchronized
	 * 
	 * @return Customer
	 * @throws InterruptedException 
	 */
	public synchronized Customer fetchCustomer() {
		while (customers[first] == null) {
			try { 
				wait();
			} catch (InterruptedException e) { }
		}
		
		Customer customer = customers[first];
		gui.emptyLoungeChair(first);
		
		customers[first] = null;
		incrementFirst();
		
		notifyAll();
		return customer;
	}
	
	private void incrementFirst() {
		first = (first + 1) % customers.length; 
	}
	
	private void incrementLast() {
		last = (last + 1) % customers.length; 
	}
}
